/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Sablony;


import java.util.TreeSet;

import java.io.File;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
 
import org.w3c.dom.*;

/**
 *  
 * @author MartinaHlinková
 */
public class SablonaKlientov implements Comparable<SablonaKlientov> {
    private String nazov;
    private TreeSet<Klient> klientiVSablone;
    
    public SablonaKlientov(String nazov){
        this.nazov = nazov;
        this.klientiVSablone = new TreeSet<Klient>();
    }
    
    public String getNazov(){
        return this.nazov;
    }
    
    public TreeSet<Klient> getKlientiVSablone(){
        return this.klientiVSablone;
    }
    public boolean pridajKlienta(Klient novy){
        if(novy == null || (novy instanceof Klient == false)) return false;
        if(novy.getIDKlienta() < 10 || novy.getIDKlienta() >= 100) return false;
        if(this.klientiVSablone.contains(novy) == true) return false;
        return this.klientiVSablone.add(novy);
        
    }
    
    public boolean odoberKlienta(int ID){
        for(Klient iterator: this.klientiVSablone){
           if(iterator.getIDKlienta() == ID){
               this.klientiVSablone.remove(iterator);
               return true;
           }
        }
        return false;
    }
    
    public boolean odoberKlienta(Klient klient){
        if(klient == null){
            return false;
        }
          if(this.klientiVSablone.contains(klient)){
              this.klientiVSablone.remove(klient);
              return true;
          }
        return false;
    }
    
    public String[][] sablonaKlientovToArray(){
        int pocet = klientiVSablone.size();
        String[][] sablonaArray = new String[pocet][2];
        int i = 0;
        for(Klient iterator: klientiVSablone){
            sablonaArray[i] = iterator.klientToArray();
            i++;
        }
        return sablonaArray;
    }
    
    public int pocetKlientov(){
        return this.klientiVSablone.size();
    }
    
    public Klient najdiKlientaPodlaID(int id){
        if( id < 10 || id > 99)return null;
        for(Klient iterator:this.klientiVSablone){
            if(iterator.getIDKlienta() == id){
                return iterator;
            }
        }
        return null;
    }
    
    public void novaXMLSablona(){
         try {
		DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
 
		// root elements
		Document doc = docBuilder.newDocument();
		Element rootElement = doc.createElement("sablonaKlientov");
		doc.appendChild(rootElement);
                for(Klient iterator: this.klientiVSablone){
                    
                    Element klient = doc.createElement("klient");
                    rootElement.appendChild(klient);
                
                    Attr attr = doc.createAttribute("id");
                    attr.setValue(Integer.toString(iterator.getIDKlienta()));
                    klient.setAttributeNode(attr);
                    
                    Element meno = doc.createElement("meno");
                    meno.appendChild(doc.createTextNode(iterator.getMenoKlienta()));
                    klient.appendChild(meno);
                    
                    Element pritomnosti = doc.createElement("pritomnostiKlienta");
                    
                    
                    for(Sablony.PritomnostKlientov iter:iterator.getPritomnostKlienta()){
                        Element pritom = doc.createElement("pritomnost");
                        
                        Attr stav = doc.createAttribute("stav");
                        stav.setValue(iter.stavKlienta.toString());
                        pritom.setAttributeNode(stav);
                        
                        Element casOd = doc.createElement("OD");
                        
                            Attr rokOd = doc.createAttribute("rok");
                            rokOd.setValue(""+iter.pociatocnyCas.getYear());
                            casOd.setAttributeNode(rokOd);
                            
                            Attr mesiacOd = doc.createAttribute("mesiac");
                            mesiacOd.setValue(""+iter.pociatocnyCas.getMonth());
                            casOd.setAttributeNode(mesiacOd);
                            
                            Attr denOd = doc.createAttribute("den");
                            denOd.setValue(""+iter.pociatocnyCas.getDate());
                            casOd.setAttributeNode(denOd);
                            
                            Attr hodinaOd = doc.createAttribute("hodina");
                            hodinaOd.setValue(""+iter.pociatocnyCas.getHours());
                            casOd.setAttributeNode(hodinaOd);
                            
                            Attr minutaOd = doc.createAttribute("minuta");
                            minutaOd.setValue(""+iter.pociatocnyCas.getMinutes());
                            casOd.setAttributeNode(minutaOd);
                        
                        pritom.appendChild(casOd);
                        Element casDo = doc.createElement("DO");
                            
                            Attr rokDo = doc.createAttribute("rok");
                            rokDo.setValue(""+iter.konecnyCas.getYear());
                            casDo.setAttributeNode(rokDo);
                            
                            Attr mesiacDo = doc.createAttribute("mesiac");
                            mesiacDo.setValue(""+iter.konecnyCas.getMonth());
                            casDo.setAttributeNode(mesiacDo);
                            
                            Attr denDo = doc.createAttribute("den");
                            denDo.setValue(""+iter.konecnyCas.getDate());
                            casDo.setAttributeNode(denDo);
                            
                            Attr hodinaDo = doc.createAttribute("hodina");
                            hodinaDo.setValue(""+iter.konecnyCas.getHours());
                            casDo.setAttributeNode(hodinaDo);
                            
                            Attr minutaDo = doc.createAttribute("minuta");
                            minutaDo.setValue(""+iter.konecnyCas.getMinutes());
                            casDo.setAttributeNode(minutaDo);
                        
                        pritom.appendChild(casDo);
                        pritomnosti.appendChild(pritom);
                    }
                    
                    klient.appendChild(pritomnosti);
                }
		// write the content into xml file
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource source = new DOMSource(doc);
		StreamResult result = new StreamResult(new File(this.nazov+".xsk"));
 
		// Output to console for testing
		// StreamResult result = new StreamResult(System.out);
 
		transformer.transform(source, result);
 
		//System.out.println("File saved! - ");
 
	  } catch (ParserConfigurationException pce) {
		pce.printStackTrace();
	  } catch (TransformerException tfe) {
		tfe.printStackTrace();
	  }
	
    }
    
    public static SablonaKlientov nacitajSablonu(File xml){
        if(xml == null || xml.isDirectory() || !xml.isFile()) return null;
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(xml);
            doc.getDocumentElement().normalize();

            NodeList nList = doc.getElementsByTagName("klient"); // list s uzlamiKlientov
 
            // ziskanie mena sablony
                String meno = xml.getPath();
                if(meno == null)return null;
                
                char data[] = {'\\', '\\'};
                String strRegex = new String(data);
                String str[] = meno.split(strRegex);
                
                meno = str[str.length-1];
                
                char data1[] = {'\\','.', };
                strRegex = new String(data1);
                str = meno.split(strRegex);
                if(str == null || str.length != 2) return null;
                meno = str[0];
               // System.out.println(meno);
            // vytvorenie prazdnej sablony
                SablonaKlientov nacitanaSablona = new SablonaKlientov(meno);
                
            for (int i = 0; i < nList.getLength(); i++) { //for pre kazdy uzol klienta
 
		Node nNode = nList.item(i);
 
		if (nNode.getNodeType() == Node.ELEMENT_NODE) {
 
			Element eElement = (Element) nNode;
                        
                        int id = Integer.parseInt(eElement.getAttribute("id"));
                        String menoKlienta = eElement.getElementsByTagName("meno").item(0).getTextContent();
			
                        Klient nacitanyKlient = new Klient(id,menoKlienta);
                        NodeList listPritomnosti = eElement.getElementsByTagName("pritomnost");// uzly pritomnosti klienta
                        for (int j = 0; j < listPritomnosti.getLength(); j++) {// for pre kazdy uzol pritomnosti
                            StavKlienta stav;
                            Node nodePritomnost = listPritomnosti.item(j);
                            
                            if (nodePritomnost.getNodeType() == Node.ELEMENT_NODE) {
                                Element ePritomnost = (Element) nodePritomnost;
                                
                                String stavString = ePritomnost.getAttribute("stav");
                                if(stavString.contains("LAHKY")){
                                    stav = StavKlienta.LAHKY;
                                }else{
                                    stav = StavKlienta.TAZKY;
                                }
                                
                                Node nodeOD = ePritomnost.getElementsByTagName("OD").item(0);
                                Node nodeDO = ePritomnost.getElementsByTagName("DO").item(0);
                                
                                Date dateOD = parsujDatumZNode(nodeOD);
                                Date dateDO = parsujDatumZNode(nodeDO);
                                
                                nacitanyKlient.pridajPritomnost(dateOD, dateDO, stav);
                            }
                        }// for pre kazdy uzol pritomnosti
			
                        nacitanaSablona.pridajKlienta(nacitanyKlient);
		}// if element node
            } //for pre kazdy uzol klienta
            return nacitanaSablona;
        } catch (Exception e) {
            //e.printStackTrace();
            return null;
        }
  
        
        
    }
    
    private static Date parsujDatumZNode(Node uzol){
        int rok, mesiac, den, hodina, minuta;
        Date navrat = null;
        Element eElement = (Element) uzol;
        try{
            rok = Integer.parseInt(eElement.getAttribute("rok"));
            mesiac = Integer.parseInt(eElement.getAttribute("mesiac"));
            den = Integer.parseInt(eElement.getAttribute("den"));
            hodina = Integer.parseInt(eElement.getAttribute("hodina"));
            minuta = Integer.parseInt(eElement.getAttribute("minuta"));
            navrat = new Date(rok,mesiac,den,hodina,minuta);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return navrat;
    }
    
    public static void main(String args[]){
        System.out.println("***********************************");
        System.out.println("*Pokusny test so sablonou klientov*");
        System.out.println("***********************************");
        
        Sablony.SablonaKlientov pokus = new Sablony.SablonaKlientov("Pokusna sablona");
        
        Sablony.Klient modra = new Klient(14,"Modra");
        Sablony.Klient cervena = new Klient(41,"Cervena");
        Sablony.Klient zelena = new Klient(25,"Zelena");
        Sablony.Klient zlta = new Klient(99,"Zlta");
        
        pokus.pridajKlienta(modra);
        pokus.pridajKlienta(cervena);
        pokus.pridajKlienta(zelena);
        pokus.pridajKlienta(zlta);
        
        for(Sablony.Klient klient: pokus.klientiVSablone){
            System.out.println(klient);
        }
        
         Sablony.Klient klientNaOdobranie = new Klient(30,"Odober");
         Sablony.Klient  falosny = new Klient(62,"Falosny");
         Sablony.Klient  uzTuJe = new Klient(99,"uz tu je");
         
         if(pokus.pridajKlienta(klientNaOdobranie) == true){
             System.out.println("Pridanie klienta na odobranie");
         }else{
             System.out.println("Chyba v pridavani.");
         }
         for(Sablony.Klient klient: pokus.klientiVSablone){
            System.out.println(klient);
        }
         if(pokus.odoberKlienta(klientNaOdobranie) == true){
             System.out.println("Podarilo sa odobrat klienta");
         }else{
             System.out.println("Doslo k chybe.");
         }
         if(pokus.odoberKlienta(falosny) == false){
             System.out.println("Spravne neodobratie klienta");
         }else{
             System.out.println("Chyba v odoberani klienta");
         }
         if(pokus.pridajKlienta(uzTuJe)== false){
             System.out.println("Sprvne nepridnie klienta");
         }else{
             System.out.println("Chyba v pridavani klienta");
         }
         if(pokus.odoberKlienta(41) == true){
             System.out.println("Spravne odobratie klienta cez ID");
         }else{
             System.out.println("Chyba v odoberaniklienta cez ID");
         }
         
         pokus.novaXMLSablona();
    }

    
    @Override
     public boolean equals(Object o){
        if(o == this){
            return true;
        }
        if(o instanceof SablonaKlientov == false){
            return false;
        }
        boolean rovnake = (this.getNazov().equals(((SablonaKlientov) o).getNazov()));
        return rovnake;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        String nazovHash = this.getNazov();
        for(int i = 0; i< nazovHash.length(); i++){
            hash = hash*nazovHash.charAt(i)%Integer.MAX_VALUE;
        }
        return hash;
    }

    public int compareTo(SablonaKlientov o) {
        return this.getNazov().compareTo(o.getNazov());
    }
    
    public int pocetKlientovVDatume(Date datum){
        int navrat = 0;
        for(Klient iterator: this.getKlientiVSablone()){
            Sablony.StavKlienta stav = iterator.klientVCentre(datum) ;
            if(stav != null){
                if(stav == Sablony.StavKlienta.LAHKY) navrat++;
                else navrat +=2;
            }
        } 
        return ((navrat/2)+(navrat%2));
    }
}
